home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmcd-1.4 / libdi.d / os_aux.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-10  |  6.5 KB  |  297 lines

  1. /*
  2.  *   libdi - CD Audio Player Device Interface Library
  3.  *
  4.  *   Copyright (C) 1995  Ti Kan
  5.  *   E-mail: ti@amb.org
  6.  *
  7.  *   This program is free software; you can redistribute it and/or modify
  8.  *   it under the terms of the GNU General Public License as published by
  9.  *   the Free Software Foundation; either version 2 of the License, or
  10.  *   (at your option) any later version.
  11.  *
  12.  *   This program is distributed in the hope that it will be useful,
  13.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *   GNU General Public License for more details.
  16.  *
  17.  *   You should have received a copy of the GNU General Public License
  18.  *   along with this program; if not, write to the Free Software
  19.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  */
  21.  
  22. /*
  23.  *   Apple A/UX version 3.x support
  24.  *
  25.  *   Contributing author: Eric Rosen
  26.  *
  27.  *   This software fragment contains code that interfaces the CD player
  28.  *   application to the Apple A/UX operating system.  The name "Apple"
  29.  *   is used here for identification purposes only.
  30.  */
  31. #ifndef LINT
  32. static char *_os_aux_c_ident_ = "@(#)os_aux.c    5.6 94/12/28";
  33. #endif
  34.  
  35. #include "common.d/appenv.h"
  36. #include "common.d/util.h"
  37. #include "libdi.d/libdi.h"
  38. #include "libdi.d/scsipt.h"
  39.  
  40.  
  41. #if defined(macII) && defined(DI_SCSIPT) && !defined(DEMO_ONLY)
  42.  
  43. extern appdata_t    app_data;
  44. extern bool_t        scsipt_notrom_error;
  45. extern FILE        *errfp;
  46.  
  47. STATIC int        pthru_fd = -1;    /* Passthrough device file desc */
  48.  
  49.  
  50. /*
  51.  * pthru_send
  52.  *    Build SCSI CDB and send command to the device.
  53.  *
  54.  * Args:
  55.  *    opcode - SCSI command opcode
  56.  *    addr - The "address" portion of the SCSI CDB
  57.  *    buf - Pointer to data buffer
  58.  *    size - Number of bytes to transfer
  59.  *    rsvd - The "reserved" portion of the SCSI CDB
  60.  *    length - The "length" portion of the SCSI CDB
  61.  *    param - The "param" portion of the SCSI CDB
  62.  *    control - The "control" portion of the SCSI CDB
  63.  *    rw - Data transfer direction flag (READ_OP or WRITE_OP)
  64.  *    prnerr - Whether an error message should be displayed
  65.  *         when a command fails
  66.  *
  67.  * Return:
  68.  *    TRUE - command completed successfully
  69.  *    FALSE - command failed
  70.  */
  71. bool_t
  72. pthru_send(
  73.     byte_t        opcode,
  74.     word32_t    addr,
  75.     byte_t        *buf,
  76.     word32_t    size,
  77.     byte_t        rsvd,
  78.     word32_t    length,
  79.     byte_t        param,
  80.     byte_t        control,
  81.     byte_t        rw,
  82.     bool_t        prnerr
  83. )
  84. {
  85.     struct userscsireq    sc_cmd;
  86.     uchar            cdb[12];
  87.     req_sense_data_t    sense_data;
  88.  
  89.  
  90.     if (pthru_fd < 0 || scsipt_notrom_error)
  91.         return FALSE;
  92.  
  93.     memset(&sc_cmd, 0, sizeof(sc_cmd));
  94.     memset(cdb, 0, sizeof(cdb));
  95.     memset(&sense_data, 0, sizeof(sense_data));
  96.     sc_cmd.cmdbuf = cdb;
  97.  
  98.     /* set up SCSI CDB */
  99.     switch (opcode & 0xf0) {
  100.     case 0xa0:
  101.     case 0xe0:
  102.         /* 12-byte commands */
  103.         sc_cmd.cmdbuf[0] = opcode;
  104.         sc_cmd.cmdbuf[1] = param;
  105.         sc_cmd.cmdbuf[2] = (addr >> 24) & 0xff;
  106.         sc_cmd.cmdbuf[3] = (addr >> 16) & 0xff;
  107.         sc_cmd.cmdbuf[4] = (addr >> 8) & 0xff;
  108.         sc_cmd.cmdbuf[5] = (addr & 0xff);
  109.         sc_cmd.cmdbuf[6] = (length >> 24) & 0xff;
  110.         sc_cmd.cmdbuf[7] = (length >> 16) & 0xff;
  111.         sc_cmd.cmdbuf[8] = (length >> 8) & 0xff;
  112.         sc_cmd.cmdbuf[9] = length & 0xff;
  113.         sc_cmd.cmdbuf[10] = rsvd;
  114.         sc_cmd.cmdbuf[11] = control;
  115.  
  116.         sc_cmd.cmdlen = 12;
  117.         break;
  118.  
  119.     case 0xc0:
  120.     case 0xd0:
  121.     case 0x20:
  122.     case 0x30:
  123.     case 0x40:
  124.         /* 10-byte commands */
  125.         sc_cmd.cmdbuf[0] = opcode;
  126.         sc_cmd.cmdbuf[1] = param;
  127.         sc_cmd.cmdbuf[2] = (addr >> 24) & 0xff;
  128.         sc_cmd.cmdbuf[3] = (addr >> 16) & 0xff;
  129.         sc_cmd.cmdbuf[4] = (addr >> 8) & 0xff;
  130.         sc_cmd.cmdbuf[5] = addr & 0xff;
  131.         sc_cmd.cmdbuf[6] = rsvd;
  132.         sc_cmd.cmdbuf[7] = (length >> 8) & 0xff;
  133.         sc_cmd.cmdbuf[8] = length & 0xff;
  134.         sc_cmd.cmdbuf[9] = control;
  135.  
  136.         sc_cmd.cmdlen = 10;
  137.         break;
  138.  
  139.     case 0x00:
  140.     case 0x10:
  141.         /* 6-byte commands */
  142.         sc_cmd.cmdbuf[0] = opcode;
  143.         sc_cmd.cmdbuf[1] = param;
  144.         sc_cmd.cmdbuf[2] = (addr >> 8) & 0xFF;
  145.         sc_cmd.cmdbuf[3] = addr & 0xFF;
  146.         sc_cmd.cmdbuf[4] = length & 0xFF;
  147.         sc_cmd.cmdbuf[5] = control;
  148.  
  149.         sc_cmd.cmdlen = 6;
  150.         break;
  151.  
  152.     default:
  153.         if (app_data.scsierr_msg && prnerr)
  154.             fprintf(errfp, "0x%02x: Unknown SCSI opcode\n",
  155.                 opcode);
  156.         return FALSE;
  157.     }
  158.  
  159.     DBGDUMP("SCSI CDB bytes", (byte_t *) sc_cmd.cmdbuf, sc_cmd.cmdlen);
  160.  
  161.     sc_cmd.databuf = buf;        /* data to transfer and */
  162.     sc_cmd.datalen = size;        /* number of bytes to transfer */
  163.     sc_cmd.datasent    = 0;
  164.  
  165.     sc_cmd.sensebuf    = (uchar *) &sense_data;    
  166.     sc_cmd.senselen    = (uchar) SZ_RSENSE;
  167.  
  168.     if (size != 0 && rw == READ_OP)
  169.         sc_cmd.flags |= SRQ_READ;
  170.  
  171.     sc_cmd.timeout = 5;        /* allow 5 seconds */
  172.  
  173.     /* Send the command down via the "pass-through" interface */
  174.     if (ioctl(pthru_fd, SCSISTART, (uchar *) &sc_cmd) < 0) {
  175.         if (app_data.scsierr_msg && prnerr) 
  176.             perror("SCSISTART ioctl failed");
  177.         return FALSE;
  178.     }
  179.  
  180.     if (sc_cmd.ret != SMG_COMP && sc_cmd.ret != SMG_LNKFLG) {
  181.         if (app_data.scsierr_msg && prnerr) {
  182.             fprintf(errfp, "CD audio: %s %s:\n%s=0x%x %s=0x%x",
  183.                 "SCSI bus status error on",
  184.                 app_data.device,
  185.                 "Opcode",
  186.                 opcode,
  187.                 "Status",
  188.                 sc_cmd.msg);
  189.  
  190.             if (sense_data.valid == 0)
  191.                 fprintf(errfp, "\n");
  192.             else {
  193.                 fprintf(errfp,
  194.                     " Key=0x%x Code=0x%x Qual=0x%x\n",
  195.                     sense_data.key,
  196.                     sense_data.code,
  197.                     sense_data.qual);
  198.             }
  199.         }
  200.         return FALSE;
  201.     }
  202.  
  203.     if (sc_cmd.stat != 0) {
  204.         if (app_data.scsierr_msg && prnerr) {
  205.             fprintf(errfp, "CD audio: %s %s:\n%s=0x%x %s=0x%x\n",
  206.                 "adapter status error on",
  207.                 app_data.device,
  208.                 "Opcode",
  209.                 opcode,
  210.                 "Status",
  211.                 sc_cmd.stat);
  212.         }
  213.         return FALSE;
  214.     }
  215.  
  216.     return TRUE;
  217. }
  218.  
  219.  
  220. /*
  221.  * pthru_open
  222.  *    Open SCSI pass-through device
  223.  *
  224.  * Args:
  225.  *    path - device path name string
  226.  *
  227.  * Return:
  228.  *    TRUE - open successful
  229.  *    FALSE - open failed
  230.  */
  231. bool_t
  232. pthru_open(char *path)
  233. {
  234.     struct stat    stbuf;
  235.     char        errstr[ERR_BUF_SZ];
  236.  
  237.     /* Check for validity of device node */
  238.     if (stat(path, &stbuf) < 0) {
  239.         sprintf(errstr, app_data.str_staterr, path);
  240.         cd_fatal_popup(app_data.str_fatal, errstr);
  241.         return FALSE;
  242.     }
  243.  
  244.     if (!S_ISCHR(stbuf.st_mode)) {
  245.         sprintf(errstr, app_data.str_noderr, path);
  246.         cd_fatal_popup(app_data.str_fatal, errstr);
  247.         return FALSE;
  248.     }
  249.  
  250.     if ((pthru_fd = open(path, O_RDONLY, NULL)) < 0) {
  251.         DBGPRN(errfp, "Cannot open %s: errno=%d\n", path, errno);
  252.         return FALSE;
  253.     }
  254.  
  255.     return TRUE;
  256. }
  257.  
  258.  
  259. /*
  260.  * pthru_close
  261.  *    Close SCSI pass-through device
  262.  *
  263.  * Args:
  264.  *    Nothing.
  265.  *
  266.  * Return:
  267.  *    Nothing.
  268.  */
  269. void
  270. pthru_close(void)
  271. {
  272.     if (pthru_fd >= 0) {
  273.         close(pthru_fd);
  274.         pthru_fd = -1;
  275.     }
  276. }
  277.  
  278.  
  279. /*
  280.  * pthru_vers
  281.  *    Return OS Interface Module version string
  282.  *
  283.  * Args:
  284.  *    Nothing.
  285.  *
  286.  * Return:
  287.  *    Module version text string.
  288.  */
  289. char *
  290. pthru_vers(void)
  291. {
  292.     return ("OS Interface module (for Apple A/UX 3.0)\n");
  293. }
  294.  
  295. #endif    /* macII DI_SCSIPT DEMO_ONLY */
  296.  
  297.